\documentclass[twoside,a4paper]{article}
\usepackage{geometry}
\geometry{margin=1.5cm, vmargin={0pt,1cm}}
\setlength{\topmargin}{-1cm}
\setlength{\paperheight}{29.7cm}
\setlength{\textheight}{25.3cm}

% useful packages.
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{enumerate}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{fancyhdr}
\usepackage{layout}
\usepackage{tikz}
\usepackage{pgf-umlcd}

% some common command
\newcommand{\dif}{\mathrm{d}}
\newcommand{\avg}[1]{\left\langle #1 \right\rangle}
\newcommand{\difFrac}[2]{\frac{\dif #1}{\dif #2}}
\newcommand{\pdfFrac}[2]{\frac{\partial #1}{\partial #2}}
\newcommand{\OFL}{\mathrm{OFL}}
\newcommand{\UFL}{\mathrm{UFL}}
\newcommand{\fl}{\mathrm{fl}}
\newcommand{\op}{\odot}
\newcommand{\Eabs}{E_{\mathrm{abs}}}
\newcommand{\Erel}{E_{\mathrm{rel}}}

\begin{document}

\pagestyle{fancy}
\fancyhead{}
\lhead{NAME Jiatu Yan}
\chead{Numerical ODE/PDE Project02 - design}
\rhead{Date 2021.6.9}


\section*{I. UML figure for the programs.}

\subsection*{The restriction and interpolation operators.} 

\begin{figure}[ht]
	\centering
	\caption{UML figure for the Restriction and Interpolation Operators.}
	\label{fig1}
\begin{tikzpicture}
	
	\tiny{	\begin{abstractclass}[text width=4cm]{RestrictionOperator<DIM>}{2.5, -2}
			\operation[0]{+operator()(MultigridVector<DIM>\& \_v,
			 const size\_t \_stepl \_M) const : void}
	\end{abstractclass}

	\begin{abstractclass}[text width=4cm]{InterpolationOperator<DIM>}{2.5, -7}
			\operation[0]{+operator()(MultigridVector<DIM>\& \_v,
			 const size\_t \_M) const : void}
		\end{abstractclass}
		
	\begin{class}[text width= 4cm]{InjectionRes<DIM>}{2.5, 0}
		\inherit{RestrictionOperator<DIM>}
		\operation{+operator()(MultigridVector<DIM>\& \_v,
		 const size\_t \_M) const}
	\end{class}
	
	\begin{class}[text width= 4cm]{FullweightingRes<DIM>}{-2.5, 0}
		\inherit{RestrictionOperator<DIM>}
		\operation{+operator()(MultigridVector<DIM>\& \_v,
		const size\_t \_M) const}
	\end{class}
	
	\begin{class}[text width= 4cm]{LinearInterpolation<DIM>}{-2.5, -9}
		\inherit{InterpolationOperator<DIM>}
		\operation{+operator()(MultigridVector<DIM>\& \_v,
		const size\_t \_M) const}
	\end{class}
	
	\begin{class}[text width= 4cm]{QuadraticInterpolation<DIM>}{2.5, -9}
		\inherit{InterpolationOperator<DIM>}
		\operation{+operator()(MultigridVector<DIM>\& \_v,
		const size\_t \_M) const}
	\end{class}
	
	\begin{class}[text width = 6cm]{RestrictionOperatorFactory<DIM>}{9.5, -2}
		\operation{+RegisterOperator(const std::string \_OperatorId,
		CreateRestrictionOperatorCallback \_createFn) : bool}
		\operation{+UnregisterOperator(const std::string \_OperatorId) : bool}
		\operation{+CreateOperator(const std::string \_OperatorId, const std::size\_t \_p)
		: RestrictionOperator<DIM>*}
		\operation{+CreateOperator(const std::string \_OperatorId) : RestrictionOperator<DIM>*}
		\operation{+$\sim$RestrictionOperatorFactory()}
		\operation{+Instance() : static RestrictionOperatorFactory<DIM>*}
		\attribute{\#\_\_obj : static RestrictionOperaterFactory<DIM>*}
		\attribute{\#\_\_callbacks CallbackMp}
		\attribute{\#RestrictionOperatorFactory()}
	\end{class}

	\begin{class}[text width = 6cm]{InterpolationOperatorFactory<DIM>}{9.5, -6}
                \operation{+InterpolationOperator(const std::string \_OperatorId,
                CreateInterpolationOperatorCallback \_createFn) : bool}
                \operation{+UnregisterOperator(const std::string \_OperatorId) : bool}
                \operation{+CreateOperator(const std::string \_OperatorId, const std::size\_t \_p)
                : InterpolationOperator<DIM>*}
                \operation{+CreateOperator(const std::string \_OperatorId) : InterpolationOperator<DIM>*}
                \operation{+$\sim$InterpolationOperatorFactory()}
                \operation{+Instance() : static InterpolationOperatorFactory<DIM>*}
                \attribute{\#\_\_obj : static InterpolationOperaterFactory<DIM>*}
                \attribute{\#\_\_callbacks CallbackMp}
                \attribute{\#InterpolationOperatorFactory()}
        \end{class}

	\begin{class}[text width = 4cm]{MultigridVector<DIM>}{-3, -3}
		\operation{+set(const std::vector<double>\& \_u, const size\_t \_N) : void}
		\operation{+operator()(const std::vector<size\_t>\& \_coord, const size\_t \_M) const : const double\&}
		\operation{+operator()(const std::vector<size\_t>\& \_coord, const size\_t \_M) : const double\&}
		\operation{+operator()(const size\_t index, const size\_t \_M) const : const double\&}
		\operation{+operator()(const size\_t index, const size\_t \_M) : double\&}
		\operation{+get\_N() const : const size\_t}
		\operation{+get\_start\_index(const size\_t \_M) const : const size\_t}
		\operation{+clean(const size\_t \_M) : void}
		\operation{+cleanpart(const size\_t \_M) : void}
		\attribute{-\_\_N : size\_t}
		\attribute{-\_\_start\_index : std::vector<double>}
        \end{class}

	\draw[umlcd style dashed line, ->] (RestrictionOperator<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (RestrictionOperatorFactory<DIM>);
	\draw[umlcd style dashed line, ->] (InterpolationOperator<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (InterpolationOperatorFactory<DIM>);
	\draw[umlcd style dashed line, <-] (RestrictionOperator<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (MultigridVector<DIM>);
	\draw[umlcd style dashed line, <-] (InterpolationOperator<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (MultigridVector<DIM>);

}
\end{tikzpicture}
\end{figure}

I wrote a class named MultigridVector which inherites from vector in STL. The class store the all the elements of the grids,
from the finest to the coarest. Then I wrote the two operator and the factory to generate them. The structure is shown in the Figure \ref{fig1}.

\subsection*{MultigridSolvers}

For the MultigridSolvers, I wrote a class that solve the Poisson function by Multigrid methods. The implementation is 
wrote in the VC, VC-1d, FMG and FMG-1d. They can be generated by MultigridSolverFactory. For VC-1d and FMG-1d, I deal with the boundary conditioin by seperate them out.
Since it is not easy to do this in higher dimension, the two classes can only solve functions with dimension equals 1.
The VC and FMG can solve equations in space with any dimension.But there may exist some bugs that induce error for nonhomogeneous equations in higher dimensions.

\begin{figure}[ht]
	\centering
	\caption{The UML figure for MultigridSolver.}
	\label{fig2}
\begin{tikzpicture}

\tiny{  
	\begin{class}[text width=4cm]{MultigridVector<DIM>}{0, 0}
        \end{class}

	\begin{abstractclass}[text width = 4cm]{VectorFunction<DIM>}{0, -11}
		\operation[0]{+operator()(const std::vector<double>\& \_p) const : double}
	\end{abstractclass}
	
	\begin{abstractclass}[text width= 6cm]{MultigridSolver<DIM>}{0, -2}
		\operation{+set(const std::vector<double>\& \_v, const size\_t \_N,
		VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g) : void}
		\operation{+set(const std::vector<double>\& \_v, const size\_t \_N, VectorFunction<DIM>\& \_f) : void}
		\operation{+get\_N() const : const size\_t}
		\operation{+get\_U(const std::vector<size\_t>\& \_coord, const size\_t \_N) const : const double}
		\operation{+get\_F(const std::vector<size\_t>\& \_coord, const size\_t \_N) const : const double}
		\operation{+get\_U(const size\_t \_idx, const size\_t \_N) const : const double}
		\operation{+get\_F(const size\_t \_idx, const size\_t \_N) const : const double}
		\operation{+smooth(const size\_t \_M) : void}
		\operation{+solve\_coarest(const size\_t \_M) : void}
		\operation{+set\_f(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, const size\_t \_M) : void}
		\operation{+set\_f(VectorFunction<DIM>\& \_f, const size\_t \_M) : void}
		\operation{+set\_e(const size\_t \_M) : void}
		\operation{+putback\_e(const size\_t \_M) : void}
		\operation{+get\_E(VectorFunction<DIM>\& \_g) const : const double}
		\operation[0]{+Solve(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, std::vector<double>\& \_v,
			 const size\_t \_N, const size\_t \_M, const size\_t itr\_num,  const size\_t nu1, const size\_t nu2, const double \_epsilon) : void}
		\attribute{-\_\_I\_2h\_2\_h : InterpolationOperator<DIM>\*}
		\attribute{-\_\_I\_h\_2\_2h : RestrictionOperator<DIM>\*}
		\attribute{-\_\_U : MultigridVector<DIM>}
		\attribute{-\_\_U : MultigridVector<DIM>}
	\end{abstractclass}

	\begin{class}[text width=5cm]{VC<DIM>}{6, 0}
		\inherit{MultigridSolver<DIM>}
		\operation{+Solve(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, std::vector<double>\& \_v, 
                        const size\_t \_N, const size\_t \_M, const size\_t itr\_num,  const size\_t nu1, const size\_t nu2, const double \_epsilon) : void}
	\end{class}
	
	\begin{class}[text width=5cm]{FMG<DIM>}{6, -3}
		\inherit{MultigridSolver<DIM>}
		\operation{+Solve(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, std::vector<double>\& \_v,
                        const size\_t \_N, const size\_t \_M, const size\_t itr\_num,  const size\_t nu1, const size\_t nu2, const double \_epsilon) : void}
	\end{class}

	\begin{class}[text width=5cm]{VC-1d}{6, -6}
		\inherit{MultigridSolver<DIM>}
		\operation{+Solve(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, std::vector<double>\& \_v,
                       const size\_t \_N, const size\_t \_M, const size\_t itr\_num,  const size\_t nu1, const size\_t nu2, const double \_epsilon) : void}
	\end{class}

	\begin{class}[text width=5cm]{FMG-1d}{6, -9}
		\inherit{MultigridSolver<DIM>}
		\operation{+Solve(VectorFunction<DIM>\& \_f, VectorFunction<DIM>\& \_g, std::vector<double>\& \_v,
                        const size\_t \_N, const size\_t \_M, const size\_t itr\_num,  const size\_t nu1, const size\_t nu2, const double \_epsilon) : void}
	\end{class}

	\begin{class}[text width = 6cm]{MultigridSolverFactory<DIM>}{12, -4}
                \operation{+RegisterMethod(const std::string \_MethodId,
                 CreateMultigridSolverCallback \_createFn) : bool}
                \operation{+UnregisterMethod(const std::string \_MethodId) : bool}
                \operation{+CreateMethod(const std::string \_MethodId, const std::size\_t \_p)
                : RestrictionMethod<DIM>*}
                \operation{+CreateMethod(const std::string \_MethodId) : MultigridSolver<DIM>*}
                \operation{+$\sim$MultigridSolverFactory()}
                \operation{+Instance() : static MultigridSolverFactory<DIM>*}
                \attribute{\#\_\_obj : static MultigridSolverFactory<DIM>*}
                \attribute{\#\_\_callbacks CallbackMp}
                \attribute{\#MultigridSolverFactory()}
        \end{class}

	\draw[umlcd style dashed line, ->] (MultigridSolverFactory<DIM>) -- node[above, sloped, black]{} (VC<DIM>);
	\draw[umlcd style dashed line, ->] (MultigridSolverFactory<DIM>) -- node[above, sloped, black]{} (VC-1d);
	\draw[umlcd style dashed line, ->] (MultigridSolverFactory<DIM>) -- node[above, sloped, black]{} (FMG<DIM>);
	\draw[umlcd style dashed line, ->] (MultigridSolverFactory<DIM>) -- node[above, sloped, black]{} (FMG-1d);
        \draw[umlcd style dashed line, ->] (MultigridSolver<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (VectorFunction<DIM>);
        \draw[umlcd style dashed line, ->] (MultigridSolver<DIM>) -- node[above, sloped, black]{$<<$import$ >>$} (MultigridVector<DIM>);


}
\end{tikzpicture}
\end{figure}

\subsection*{VectorFunctions}

For the functions I also wrote a factory to generate them. Thus I can change the functions in main program by rewriting the inputfile.
\begin{figure}[ht]
        \centering
        \caption{The UML figure for VectorFunctions.}
        \label{fig3}
\begin{tikzpicture} 
	\tiny{
		\begin{abstractclass}[text width = 6cm]{VectorFunction<DIM>}{2, -2}
			\operation[0]{+operator()(const std::vector<double>\& \_p) const : double}
		\end{abstractclass}

		\begin{abstractclass}[text width = 6cm]{MultigridSolver<DIM>}{2, 0}
		\end{abstractclass}
		
		\begin{class}[text width = 6cm]{function<DIM>}{2, -4}
			\inherit{VectorFunction<DIM>}
			\operation[0]{+operator()(const std::vector<double>\& \_p) const : double}
		\end{class}
		
		\begin{class}[text width = 6cm]{VectorFunctionFactory<DIM>}{10, -2}
                \operation{+RegisterFunction(const std::string \_FunctionId,
                 CreateVectorFunctionCallback \_createFn) : bool}
                \operation{+UnregisterFunction(const std::string \_FunctionId) : bool}
		\operation{+CreateFunction(const std::string \_FunctionId, const std::size\_t \_p)
                : RestrictionFunction<DIM>*}
                \operation{+CreateFunction(const std::string \_FunctionId) : VectorFunction<DIM>*}
                \operation{+$\sim$VectorFunctionFactory()}
                \operation{+Instance() : static VectorFunctionFactory<DIM>*}
                \attribute{\#\_\_obj : static VectorFunctionFactory<DIM>*}
                \attribute{\#\_\_callbacks CallbackMp}
                \attribute{\#VectorFunctionFactory()}
	\end{class}

		\draw[umlcd style dashed line, ->] (VectorFunctionFactory<DIM>) -- node[above, sloped, black]{} (function<DIM>);
        \draw[umlcd style dashed line, ->] (MultigridSolver<DIM>) -- node[above, sloped, black]{} (VectorFunction<DIM>);
	}
\end{tikzpicture}
\end{figure}




\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
